/**
 * 测试用例TCF格式导出
 *
 * Created by snowingsea on 2021/02/01.
 */
const fs = require('fs-extra');
const path = require('path');
const compressing = require('compressing');
const moment = require('moment');
const functions = require('../../../functions');
const tests = require('../../../tests');
const BaseTestCasesExporter = require('./../base-exporter');
const TCFTestCaseTransformer = require('./tcf-test-case-transformer');
const utility = require('./../../../utility');
class TcfTestCasesExporter extends BaseTestCasesExporter {
  exportTestCases(progressIndicator) {
    const result = {
      cachePath: this.outputDir,
    };
    return new Promise((resolve, reject) => {
      this.spliteByFunction(null, progressIndicator)
        .then(() => {
          const fileName = `${this.project.projectName}-${this.version.versionName}.test-cases.tcf.zip`;
          result.testsPath = path.join(this.outputDir, fileName);
          const testsDir = path.join(this.outputDir, this.project.projectName);
          return compressing.zip.compressDir(testsDir, result.testsPath);
        })
        .then(() => {
          resolve(result);
        })
        .catch(reject);
    });
  }

  handleFunction(func, file, typeSystem, versionDir) {
    if (!file.functions || (file.functions.length > 0
      && !file.functions.includes(func._id.toString()))) {
      return Promise.resolve();
    }
    return new Promise((resolve, reject) => {
      const { functionName } = func;
      const testsPath = `${path.join(versionDir, file.path, functionName)}.tcf`;
      super.handleFunction(func, file, typeSystem, versionDir)
        .then(() => fs.ensureDir(path.dirname(testsPath)))
        .then(() => {
          const templatePath = path.join(__dirname, 'template.tcf.dot');
          const tcfData = {
            path: file.path,
            name: functionName,
            createDate: moment().format('MMM DD YYYY HH:mm:ss'),
            testcases: [],
            globals: [],
            globalStubs: [],
          };
          const funcVariables = functions.getFunctionVariableJson(func.variables);
          func.tests.forEach((test) => {
            const testCase = tests.getJson(test, this.i18n);
            const transformer = new TCFTestCaseTransformer(
              testCase,
              funcVariables,
              typeSystem
            );
            transformer.transform();
            tcfData.testcases.push(transformer);
            transformer.globals.forEach((global) => {
              tcfData.globals.push(global);
            });
            transformer.globalStubs.forEach((globalStub) => {
              tcfData.globalStubs.push(globalStub);
            });
          });
          return utility.getDotTemplate(templatePath, tcfData);
        })
        .then((content) => {
          content = content.split('\r\n').filter((line) => line.trim().length > 0).join('\r\n');
          return utility.writeFile(content, utility.handleWindwowFileNameSpecialCharacters(testsPath));
        })
        .then(resolve)
        .catch(reject);
    });
  }

  /**
   * 按文件分割
   * @return {Promise}
   */
  spliteByFile(callback = null, progressIndicator) {
    return new Promise((resolve, reject) => {
      const result = {};
      this.spliteByProjectVersion((versionDir) => fs.ensureDir(versionDir))
        .then(({ projectDir, versionPath, versionType }) => {
          result.projectDir = projectDir;
          result.versionPath = versionPath;
          result.versionDir = versionPath;
          result.versionType = versionType;
          return this.filterSelectedFiles();
        })
        .then(() => this.createVersionInfoFile(result.projectDir, result.versionType, 'tcf'))
        .then(() => this.handleFiles(this.fileIds, result.versionDir, callback, progressIndicator))
        .then(() => resolve(result))
        .catch(reject);
    });
  }
}

/**
 * Export model definition object.
 */
module.exports = TcfTestCasesExporter;
